<template>
  <div>
    <el-dialog
      :title="'文件预览 - ' + fileName"
      :visible.sync="dialogVisible"
      width="80%"
      :before-close="handleClose"
      class="file-preview-dialog"
      append-to-body
    >
      <!-- 加载指示器 -->
      <div v-if="loading" class="preview-loading">
        <i class="el-icon-loading" style="font-size: 32px;"></i>
        <div class="loading-text">加载中...</div>
      </div>
      
      <!-- 无法预览的文件类型 -->
      <div v-else-if="!canPreview" class="cannot-preview">
        <i class="el-icon-document"></i>
        <p>无法预览该类型的文件</p>
        <el-button type="primary" @click="downloadFile">下载文件</el-button>
      </div>

      <!-- 图片预览 -->
      <div v-else-if="fileType === 'image'" class="image-preview-container">
        <img :src="previewUrl" alt="图片预览" @load="loading = false" />
      </div>
      
      <!-- PDF预览 -->
      <div v-else-if="fileType === 'pdf'" class="pdf-preview-container">
        <iframe :src="previewUrl" width="100%" height="500" frameborder="0"></iframe>
      </div>

      <!-- 文本预览 -->
      <div v-else-if="fileType === 'text'" class="text-preview-container">
        <iframe :src="previewUrl" width="100%" height="500" frameborder="0"></iframe>
      </div>

      <!-- 音频预览 -->
      <div v-else-if="fileType === 'audio'" class="audio-preview-container">
        <audio controls style="width: 100%">
          <source :src="previewUrl" :type="'audio/' + fileExtension">
          您的浏览器不支持音频预览。
        </audio>
      </div>

      <!-- 视频预览 -->
      <div v-else-if="fileType === 'video'" class="video-preview-container">
        <video controls style="width: 100%; max-height: 500px">
          <source :src="previewUrl" :type="'video/' + fileExtension">
          您的浏览器不支持视频预览。
        </video>
      </div>

      <!-- 微软Office文档预览 (需要转换或第三方服务) -->
      <div v-else-if="fileType === 'office'" class="office-preview-container">
        <!-- 对于Office文档，我们提供下载选项和Office在线预览链接 -->
        <div class="office-preview-notice">
          <p>Office文档需要通过以下方式预览：</p>
          <el-button type="primary" @click="downloadFile" icon="el-icon-download">下载文件</el-button>
          <el-button 
            v-if="isOfficeOnlineSupported" 
            type="success" 
            @click="openOfficeOnline"
            icon="el-icon-view"
          >使用Office Online查看</el-button>
        </div>
      </div>

      <div slot="footer" class="dialog-footer">
        <el-button @click="handleClose">关闭</el-button>
        <el-button type="primary" @click="downloadFile">下载</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getToken } from "@/utils/auth";

export default {
  name: "FilePreview",
  props: {
    // 文件路径
    filePath: {
      type: String,
      required: true
    },
    // 文件名
    fileName: {
      type: String,
      default: "未知文件"
    },
    // 对话框可见性
    visible: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      dialogVisible: false,
      loading: true,
      fileType: "",
      fileExtension: "",
      canPreview: false,
      baseUrl: process.env.VUE_APP_BASE_API,
      previewUrl: "",
      downloadUrl: ""
    };
  },
  computed: {
    isOfficeOnlineSupported() {
      // 根据文件扩展名判断是否支持Office Online预览
      const supportedExtensions = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'];
      return supportedExtensions.includes(this.fileExtension);
    }
  },
  watch: {
    visible(newVal) {
      this.dialogVisible = newVal;
      if (newVal) {
        this.initPreview();
      }
    },
    dialogVisible(newVal) {
      if (!newVal) {
        this.$emit('update:visible', false);
      }
    }
  },
  methods: {
    handleClose() {
      this.dialogVisible = false;
      this.loading = true;
    },
    
    initPreview() {
      // 重置状态
      this.loading = true;
      this.canPreview = false;

      // 分析文件扩展名
      if (this.fileName && this.fileName.includes('.')) {
        this.fileExtension = this.fileName.split('.').pop().toLowerCase();
        
        // 根据扩展名确定文件类型和是否可预览
        if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(this.fileExtension)) {
          this.fileType = 'image';
          this.canPreview = true;
        } else if (this.fileExtension === 'pdf') {
          this.fileType = 'pdf';
          this.canPreview = true;
        } else if (['txt', 'csv', 'html', 'htm', 'xml', 'json', 'js', 'css'].includes(this.fileExtension)) {
          this.fileType = 'text';
          this.canPreview = true;
        } else if (['mp3', 'wav', 'ogg', 'flac'].includes(this.fileExtension)) {
          this.fileType = 'audio';
          this.canPreview = true;
        } else if (['mp4', 'webm', 'ogv'].includes(this.fileExtension)) {
          this.fileType = 'video';
          this.canPreview = true;
        } else if (['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'].includes(this.fileExtension)) {
          this.fileType = 'office';
          this.canPreview = false; // 默认不能直接预览Office文档
        } else {
          this.fileType = 'unknown';
          this.canPreview = false;
        }
      } else {
        this.fileType = 'unknown';
        this.canPreview = false;
      }

      // 设置预览URL和下载URL
      // 确保没有任何附加子目录，使用原始返回的路径
      let processedPath = this.filePath;
      
      // 如果路径包含完整的profile路径，需要提取相对路径部分
      if (processedPath.includes('/profile/')) {
        // 从/profile/之后开始截取
        processedPath = processedPath.substring(processedPath.indexOf('/profile/') + 9);
      } else if (processedPath.startsWith('/profile')) {
        // 从/profile之后开始截取
        processedPath = processedPath.substring(8);
      } else if (processedPath.startsWith('profile/')) {
        // 从profile/之后开始截取
        processedPath = processedPath.substring(8);
      }
      
      // 文件路径可能只包含文件名，此时应该加上业务模块目录
      if (!processedPath.includes('/') && !processedPath.includes('\\')) {
        processedPath = 'business/' + processedPath;
      }
      
      this.previewUrl = `${this.baseUrl}/system/business/preview-file?filePath=${encodeURIComponent(processedPath)}`;
      this.downloadUrl = `${this.baseUrl}/system/business/download-file?filePath=${encodeURIComponent(processedPath)}`;
      
      console.log("FilePreview - File Information:", {
        originalPath: this.filePath,
        processedPath,
        previewUrl: this.previewUrl,
        downloadUrl: this.downloadUrl
      });

      // 如果文件类型支持预览，则在图片加载完成时或者对于非图片类型的文件直接设置加载完成
      if (this.canPreview && this.fileType !== 'image') {
        setTimeout(() => {
          this.loading = false;
        }, 500);
      }
    },
    
    downloadFile() {
      // 不要使用 window.location.href，因为这可能导致路由错误
      // window.location.href = this.downloadUrl;
      
      const token = getToken();
      // 确保使用正确的业务控制器
      let filePath = this.filePath;
      
      // 如果文件路径包含"|"，说明是以"原始文件名|存储路径"格式存储的
      if (filePath.includes('|')) {
        // 获取最后一个"|"后的内容，这才是真正的文件路径
        const parts = filePath.split('|');
        filePath = parts[parts.length - 1]; // 取最后一个部分
      }
      
      // 如果路径包含完整的profile路径，需要提取相对路径部分
      if (filePath.includes('/profile/')) {
        // 从/profile/之后开始截取
        filePath = filePath.substring(filePath.indexOf('/profile/') + 9);
      } else if (filePath.startsWith('/profile')) {
        // 从/profile之后开始截取
        filePath = filePath.substring(8);
      } else if (filePath.startsWith('profile/')) {
        // 从profile/之后开始截取
        filePath = filePath.substring(8);
      }
      
      // 文件路径可能只包含文件名，此时应该加上业务模块目录
      if (!filePath.includes('/') && !filePath.includes('\\')) {
        filePath = 'business/' + filePath;
      }
      
      // 添加business目录前缀，如果path中不包含
      if (!filePath.startsWith('business/') && !filePath.includes('/business/')) {
        filePath = 'business/' + filePath;
      }
      
      const baseUrl = this.baseUrl;
      const url = `${baseUrl}/system/business/download-file?filePath=${encodeURIComponent(filePath)}`;
      
      console.log("FilePreview - Downloading file:", {
        fileName: this.fileName,
        originalPath: this.filePath,
        processedPath: filePath,
        downloadUrl: url
      });
      
      const xhr = new XMLHttpRequest();
      xhr.open("GET", url, true);
      xhr.responseType = "blob";
      xhr.setRequestHeader("Authorization", "Bearer " + token);
      
      xhr.onload = () => {
        if (xhr.status === 200) {
          const contentType = xhr.getResponseHeader("Content-Type");
          console.log("Download successful, content type:", contentType);
          
          // 检查内容是否为JSON（可能是错误消息）
          if (contentType && contentType.includes('application/json')) {
            const reader = new FileReader();
            reader.onload = () => {
              try {
                const response = JSON.parse(reader.result);
                console.error("Error response:", response);
                this.$modal.msgError(response.msg || "下载失败");
              } catch (e) {
                console.error("Failed to parse error response:", e);
                this.$modal.msgError("下载失败");
              }
            };
            reader.readAsText(xhr.response);
            return;
          }
          
          const blob = new Blob([xhr.response]);
          if (window.navigator.msSaveOrOpenBlob) {
            navigator.msSaveBlob(blob, this.fileName);
          } else {
            const url = window.URL.createObjectURL(blob);
            const link = document.createElement("a");
            link.href = url;
            link.setAttribute("download", this.fileName);
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            window.URL.revokeObjectURL(url);
          }
        } else {
          console.error("Download failed with status:", xhr.status);
          this.$modal.msgError(`下载失败 (${xhr.status})`);
        }
      };
      
      xhr.onerror = (e) => {
        console.error("XHR error during download:", e);
        this.$modal.msgError("下载失败 - 网络错误");
      };
      
      xhr.send();
    },
    
    openOfficeOnline() {
      // 使用Office Online预览服务，需要公网可访问URL
      // 这里使用一个假设的Office Online Viewer URL，实际实现可能需要调整
      const officeOnlineUrl = `https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(this.downloadUrl)}`;
      window.open(officeOnlineUrl, '_blank');
    }
  }
};
</script>

<style scoped>
.file-preview-dialog {
  max-width: 1200px;
}

.preview-loading,
.cannot-preview {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 400px;
}

.loading-text {
  margin-top: 16px;
  color: #909399;
}

.cannot-preview i {
  font-size: 60px;
  color: #c0c4cc;
  margin-bottom: 16px;
}

.cannot-preview p {
  margin-bottom: 20px;
  color: #909399;
}

.image-preview-container,
.pdf-preview-container,
.text-preview-container,
.office-preview-container {
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: auto;
  max-height: 70vh;
}

.image-preview-container img {
  max-width: 100%;
  max-height: 70vh;
  object-fit: contain;
}

.office-preview-notice {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 30px;
  text-align: center;
}

.office-preview-notice p {
  margin-bottom: 20px;
  color: #606266;
}

.office-preview-notice .el-button {
  margin: 8px;
}
</style> 